<?php

namespace app\storeapi\model\sharp;

use app\common\model\sharp\Goods as GoodsModel;
use app\storeapi\model\Category;
use app\storeapi\model\sharp\GoodsSku as GoodsSkuModel;
use app\storeapi\model\sharp\ActiveGoods as ActiveGoodsModel;


/**
 * 整点秒杀-商品模型
 * Class Goods
 * @package app\store\model\sharp
 */
class Goods extends GoodsModel
{
    /**
     * 获取列表数据
     * @param string $search
     * @return mixed|\think\Paginator
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getSharpList($data)
    {

        // 商品列表获取条件
        $param = array_merge([
            'search' => '',         // 搜索关键词
            'category_id' => 0,     // 分类id
            'goodsIds' => [],         // ids
            'spec_type' => 10,         // 默认单规格
        ], $data);

        // 筛选条件
        $filter = [];
        $filter['a.wxapp_id'] = $param['wxapp_id'];
        $page = isset($param['page']) && is_numeric($param['page']) ? intval($param['page']) : 1;
        $limit = 10;
        $offset = ($page - 1) * $limit;
        $param['category_id'] > 0 && $filter['b.category_id'] = ['IN', Category::getSubCategoryId($param['category_id'])];
        !empty($param['search']) && $filter['b.goods_name'] = ['like', '%' . trim($param['search']) . '%'];
        !empty($param['goodsIds'])  && $filter['a.sharp_goods_id'] = ['NOT IN', $param['goodsIds']];

        // 执行查询
        $list = $this->alias('a')
            ->join('yoshop_goods b','a.goods_id=b.goods_id')
            ->where(['a.is_delete'=>0])
            ->field('a.sharp_goods_id,a.goods_id,a.limit_num,a.seckill_stock,a.total_sales,a.status,b.goods_name,b.spec_type,b.category_id')
            ->with(['image.file', 'sku'])
            ->where($filter)
            ->order(['a.sort', 'a.goods_id' => 'desc'])
            ->limit($offset, $limit)
            ->select();

        if ($list->isEmpty()) return [];
        // 格式化商品列表
        $data = [];
        foreach ($list as $goods) {
            $data[] = [
                'sharp_goods_id' => $goods['sharp_goods_id'],//秒杀商品id
                'goods_id' => $goods['goods_id'],//商品id
                'goods_name' => $goods['goods_name'],//商品名称
                'goods_image' => $goods['image'][0]['file_path'],//商品图片
                'goods_price' => $goods['sku'][0]['seckill_price'],//商品价格
                'goods_stock_num' => $goods['seckill_stock'],//商品库存总量
                'goods_sales' => $goods['total_sales'],//商品销量
                'goods_status' => $goods['status'],//商品状态
            ];
        }
        return $data;

    }

    /**
     * 商品状态
     * @param $goods
     * @param $data
     * @return int
     */
    public function getStatusAttr($value)
    {
        $status = [0 => '下架', 1 => '上架'];
        return ['text' => $status[$value], 'value' => $value];
    }

    /**
     * 关联商品图片表
     * @return \think\model\relation\HasMany
     */
    public function image()
    {
        return $this->hasMany("app\\storeapi\\model\\GoodsImage",'goods_id','goods_id');
    }

    /**
     * 关联商品规格表
     * @return \think\model\relation\HasMany
     */
    public function sku()
    {
        return $this->hasMany("app\\common\\model\\sharp\\GoodsSku")->order(['goods_sku_id' => 'asc']);
    }

    /**
     * 获取已经添加的秒杀商品的id
     * @param $goods
     * @param $data
     * @return bool
     * @throws \Exception
     */
    public function sharpGoodsIds()
    {
        return $this->where(['wxapp_id'=>self::$wxapp_id,'is_delete'=>0])->column('goods_id');
    }


    /**
     * 添加商品
     * @param $goods
     * @param $data
     * @return bool
     * @throws \Exception
     */
    public function add($goods, $data)
    {
        // 添加商品
        $this->allowField(true)->save(array_merge($data, [
            'goods_id' => $goods['goods_id'],
            'seckill_stock' => $this->getSeckillStock($goods, $data),
            'wxapp_id' => self::$wxapp_id,
        ]));
        // 商品规格
        $this->addGoodsSpec($goods, $data);
        return true;
    }


    /**
     * 根据商品id集获取商品列表
     * @param array $goodsIds
     * @param array $param
     * @return false|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getListByIds($goodsIds, $param = [])
    {
        // 获取商品列表数据
        $list = parent::getListByIds($goodsIds, $param);
        // 整理列表数据并返回
        return $this->setGoodsListData($list, true);
    }


    /**
     * 编辑商品
     * @param $goods
     * @param $data
     * @return bool
     * @throws \Exception
     */
    public function edit($goods, $data)
    {
        // 更新商品
        $this->allowField(true)->save(array_merge($data, [
            'seckill_stock' => $this->getSeckillStock($goods, $data),
        ]));
        // 商品规格
        $this->addGoodsSpec($goods, $data, true);
        return true;
    }

    /**
     * 获取总库存数量
     * @param $goods
     * @param $data
     * @return int
     */
    private function getSeckillStock($goods, $data)
    {
        if ($goods['spec_type'] == '10') {
            return $data['sku']['seckill_stock'];
        }
        $seckillStock = 0;
        foreach ($data['spec_many']['spec_list'] as $item) {
            $seckillStock += $item['form']['seckill_stock'];
        }
        return $seckillStock;
    }

    /**
     * 验证商品ID能否被添加
     * @param $goodsId
     * @return bool
     */
    public function validateGoodsId($goodsId)
    {

        if ($goodsId <= 0) {
            $this->error = '很抱歉，您还没有选择商品';
            return false;
        }
        // 验证是否存在秒杀商品
        if ($this->isExistGoodsId($goodsId)) {
            $this->error = '很抱歉，该商品已存在，无需重复添加';
            return false;
        }
        return true;
    }

    /**
     * 商品ID是否存在
     * @param $goodsId
     * @return bool
     */
    public static function isExistGoodsId($goodsId)
    {

        return  !!(new static)->where('goods_id', '=', $goodsId)
            ->where('wxapp_id', '=', self::$wxapp_id)
            ->where('is_delete', '=', 0)
            ->value('sharp_goods_id');

    }

    /**
     * 添加商品规格
     * @param $goods
     * @param $data
     * @param bool $isUpdate
     * @return array|false|\think\Model
     * @throws \Exception
     */
    private function addGoodsSpec($goods, $data, $isUpdate = false)
    {
        // 更新模式: 先删除所有规格
        $model = new GoodsSkuModel;
        $isUpdate && $model->removeAll($this['sharp_goods_id']);
        // 添加sku (单规格)
        if ($goods['spec_type'] == '10') {
            return $this->sku()->save(array_merge($data['sku'], [
                'wxapp_id' => self::$wxapp_id,
            ]));
        }
        // 添加sku (多规格)
        return $model->addSkuList($this['sharp_goods_id'], $data['spec_many']['spec_list']);
    }



    /**
     * 软删除
     * @return false|int
     */
    public function setDelete()
    {
        // 同步删除活动会场与商品关联记录
        $model = new ActiveGoodsModel;
        $model->onDeleteSharpGoods($this['sharp_goods_id']);
        return $this->allowField(true)->save(['is_delete' => 1]);
    }

}